<?php
/*
 * <<Singleton>>
 * Context object to store universally used data like environment wrapper, and Configuration
 *
 */

m2import('admin/user.o.inc.php');
m2import('env.o.inc.php');
m2import('base/AccessFactory.php');
m2import('dba/DataSource.php');
m2import('cms/cmsTypeConf.o.inc.php');
m2import('base/AdminMediaPath.php');
m2import('base/templateEngine/DocumentContext.php');

class base_ApplicationContext {

    /**
     * @var env
     */
    private $env;
    /**
     *
     * @var array
     */
    private $xics;
    /**
     *
     * @var base_AccessFactory
     */
    public $accessFactory;
    /**
     *
     * @var user
     */
    public $user;
    /**
     *
     * @var array
     */
    private $cfgPaths;
    /**
     *
     * @var cmsTypeConf
     */
    private $typesObject = null;
    /**
     *
     * @var AdminMediaPath
     */
    private $_mediaPath;
    /**
     * Module cfgs
     * @var array
     */
    private $modCfgs = array();

    /**
     * private
     */
    function base_ApplicationContext () {
        $this->env = env::getInstance();
        $this->xics['doc_id']      = $this->env->param('doc_id');
        $this->xics['currentLang'] = $this->env->getServer('s_currentLang');
        $ds = & dba_DataSource::getInstance();
        $udba = & $ds->getConnection();
        $this->user = new user($this->env->getSession('s_user'),$udba);
        $this->accessFactory = new base_AccessFactory();
/*        // TODO: if some time far the var_paths is not included global,
        // then do it here.
        $this->cfgPaths = & $GLOBALS['cfgPaths'];*/
        $this->_mediaPath = new AdminMediaPath($this);
    }

    /**
     * singleton var
     * @var base_ApplicationContext
     */
    static private $ctx = null;

    /**
     * Get an instance of the applications context object
     *
     * static
     * @return base_ApplicationContext Context
     */
    public static function getInstance() {
        if (self::$ctx == null)
            self::$ctx = new base_ApplicationContext();
        return self::$ctx;
    }

    /**
     * Variable parameter list: for $cfgPaths['a']['b']['c'] write:
     * $ctx->cfgPath('a', 'b', 'c');
     */
    function cfgPath () {
        $val = $GLOBALS['cfgPaths'];
        foreach (func_get_args() as $arg) {
            $val = $val[$arg];
        }
        return $val;
    }

    function cfgPaths () {
        return $GLOBALS['cfgPaths'];
    }

    /**
     * Get object representing cms content types (content classes).
     *
     * @return cmsTypeConf Type configurations object
     */
    function getTypesObject() {
        if ($this->typesObject == null) {
            $dba = & $this->accessFactory->getInstanceOf(base_AccessFactory::$CMS);
            $types = $dba->getTypes();
            foreach ($GLOBALS['cfgTypes'] as $type) {
                $types[] = $type['conf'];
            }
            $this->typesObject = new cmsTypeConf($types);
        }
        return $this->typesObject;
    }

    /**
     * Return the conf string for a given type name
     *
     * @param string $name name of type
     * @return string
     */
    function getTypeConf ($name) {
        $obj = $this->getTypesObject();
        return $obj->getConfArray($name);
    }

    /**
     * Variable parameter list: for $GLOBALS['cfgXX']['b']['c'] write:
     * $ctx->cfg('XX', 'b', 'c');
     *
     * @param string $key Key/name of the config variable
     */
    function cfg ($key) {
        $val = $GLOBALS['cfg'.$key];
        $args = func_get_args();
        array_shift($args);
        while ($arg = array_shift($args)) {
            $val = $val[$arg];
        }
        return $val;
    }

    function getModuleNames () {
        $dir = dir($this->cfgPath('basePath').'/modules');
        $modules = array();
        while (false !== ($entry = $dir->read())) {
            if ($entry[0] != '.' && $entry != 'core') {
                $modules[] = $entry;
            }
        }
        return $modules;
    }

    /**
     * Get the absolute path of a file within a module
     *
     * @param string $module Name of the module
     * @param string $file   File path relative to the module root
     * @return string The absolute path
     */
    function getFilepathByModule ($module, $file) {
        return $this->modPath($module).$file;
    }

    /**
     * Authenticate user with username and password from login form. If these are not send,
     * the authentication state of the user is checked. If a logout is sent, then the user is
     * logged out and then redirected to the login page.
     *
     * @return boolean Is the user authenticated?
     */
    function authenticate() {
        $this->user->authenticate($this->env->getParam('IS_LOGIN_USR'),
            $this->env->getParam('IS_LOGIN_PWD'));
        if ($this->env->getParam('IS_LOGOUT'))
            $this->user->logout();
        $this->env->setSession('s_user',$this->user->exportUserData());
        return $this->user->isAuthenticated();
    }

    /**
     * Get the environment variable wrapper (for $_GET, $_POST etc)
     *
     * @return env Env wrapper instance.
     */
    function & getEnvWrapper () {
        return $this->env;
    }

    /**
     * Get the user object for permission checking and user data access, etc.
     * @return user User object
     */
    function getUsr () {
        return $this->user;
    }

    /**
     *
     * @return AdminMediaPath
     */
    function mediaPath () {
        return $this->_mediaPath;
    }

    /**
     * Generate jQuery Include Code
     * @return string
     */
    function jQueryInclude () {
        return '		<link type="text/css" href="'.$this->mediaPath()->main().'css/cupertino/jquery-ui-1.8.4.custom.css" rel="stylesheet" />
		<script type="text/javascript" src="'.$this->mediaPath()->main().'js/jquery-1.6.1.min.js"></script>
		<script type="text/javascript" src="'.$this->mediaPath()->main().'js/jquery-ui-1.8.4.custom.min.js"></script>
';
    }

    /**
     * Admin mod path with prepended slash
     * @return string
     */
    function modPath ($modulename) {
        return $this->cfgPath('basePath').'modules/'.$modulename.'/';
    }

    /**
     *
     * @return base_AccessFactory
     */
    function getAccessFactory () {
        return $this->accessFactory;
    }

    /**
     *
     * @var base_templateEngine_DocumentContext
     */
    private $currentDocCtx = null;

    /**
     *
     * @return base_templateEngine_DocumentContext
     */
    public function getDocumentContext () {
        return $this->currentDocCtx;
    }

    /**
     * Create a new DocumentContext for use with
     *
     * @return base_templateEngine_DocumentContext
     */
    public function setCurrentDocumentContext (base_templateEngine_DocumentContext $ctx) {
        $this->currentDocCtx = $ctx;
    }

    /**
     * Create a new DocumentContext for use with
     *
     * @param int $doc_id Doc ID
     * @param mixed $lang Language ID or array with indexes 'id' and 'name' for language
     * @param string $buildMode BuildMode
     * @param string $medium Medium
     * @return base_templateEngine_DocumentContext
     */
    public function createDocumentContext ($doc_id, $lang, $buildMode, $medium) {
        $ctx = new base_templateEngine_DocumentContext($doc_id, $lang, null, '', $buildMode, $medium);
        return $ctx;
    }

}
